// ==================================================================================
// Shared Genomics Project MPI Codebase
// Version 1.0 30/04/2010
//
// (c) 2010 University of Manchester all rights reserved
//
// This file is distributed under the GNU General Public License, Version 2.  
// Please see the file COPYING.txt for more details
// ==================================================================================

/*!
\file
\brief Implementation of Gender and Founder Data 
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "copyfile.h"
#include "foundersfile.h"
#include "suffixes.h"
#include "utils.h"

int foundersfile_create(struct pedfile *p, struct selected_options *ops) {
	BOOL jobDone = FALSE;
	char filepath[FILE_PATH_LENGTH];
	FILE *out = NULL;
	
	if (p == NULL || ops == NULL) return 0;
	else if (p->nSample == 0) return 0;
	else if (strlen(ops->szRunId) == 0 || strlen(ops->ldir) == 0) return 0;

	sprintf(filepath, "%s%s%s", ops->ldir, ops->szRunId, SUFFIX_FOUNDERS_FILE);
	out = fopen(filepath, "wb");
	if (out != NULL) {
		int i;

		fwrite(&p->nSample, sizeof(int), 1, out); // No. samples

		// Right the gender block first.
		for (i = 0; i < p->nSample; i++) fwrite(&p->sample[i]->sex, sizeof(BOOL), 1, out);
			
		// Founders flags second
		for (i = 0; i < p->nSample; i++) fwrite(&p->sample[i]->founder, sizeof(BOOL), 1, out);

		// Written the data in 2 lumps to avoid excessive index arithmetic when accessing the data.

		fclose(out);
		jobDone = TRUE;
	}
	
	if (jobDone) return 1;
	else return 0;
}

BOOL* foundersfile_load(struct selected_options *ops, int *nSamples) {
	FILE *in = NULL;
	BOOL *data = NULL;
	
	if (ops == NULL || nSamples == NULL) return NULL;
	else if (strlen(ops->szFoundersFileName) == 0) return NULL;

	*nSamples = 0;
	in = fopen(ops->szFoundersFileName, "rb"); 
	if (in != NULL) {
		if (fread(nSamples, sizeof(int), 1, in) == 1) {
			if (*nSamples > 0) {
				data = create_bool_array((*nSamples) * 2, TRUE);
				if (data != NULL) {
					if (fread(data, sizeof(BOOL) * 2 * (*nSamples), 1, in) != 1) {
						// I/O failure so drop the data array.
						*nSamples = 0;
						free(data);
						data = NULL;
					}
				}
			}
		}
		fclose(in);
	}

	return data;
}

// Locally temporarily appending rank to the run ID to increase the uniqueness of the output file name.
int foundersfile_create_and_copy(struct pedfile *p, struct selected_options *ops, int rank) {
	BOOL jobDone = FALSE;
	char tmp_szRunId[TOKEN_LENGTH];

	if (ops == NULL || p == NULL) return 0;

	strcpy(tmp_szRunId, ops->szRunId);
	sprintf(ops->szRunId, "%s_%i", tmp_szRunId, rank);

	if (foundersfile_create(p, ops)) {
		char localFilepath[FILE_PATH_LENGTH], remoteFilepath[FILE_PATH_LENGTH];
		sprintf(localFilepath, "%s%s%s", ops->ldir, ops->szRunId, SUFFIX_FOUNDERS_FILE);
		sprintf(remoteFilepath, "%s%s%s", ops->rdir, tmp_szRunId, SUFFIX_FOUNDERS_FILE);
		if (copyAndDeleteFile(localFilepath, remoteFilepath)) jobDone = TRUE;
	}

	strcpy(ops->szRunId, tmp_szRunId); // Restore the original Run ID

	if (jobDone) return 1;
	else return 0;
}
